from typing import Generic, Optional, TypeVar, List, Any

from fastapi import Query
from pydantic import BaseModel, Field

T = TypeVar("T")


class ApiResponse(BaseModel, Generic[T]):
	code: int = Field(200, description="业务状态码")
	message: str = Field("success", description="描述信息")
	data: Optional[Any] = Field(None, description="返回数据")
	error_code: Optional[str] = Field(None, description="业务错误码")
	details: Optional[dict] = Field(None, description="详细错误信息")

	@staticmethod
	def success(data: Optional[Any] = None, message: str = "success"):
		return ApiResponse[Any](code=200, message=message, data=data, error_code=None, details=None)

	@staticmethod
	def error(message: str = "error", code: int = 400, error_code: Optional[str] = None,
			  details: Optional[dict] = None):
		return ApiResponse[Any](
			code=code,
			message=message,
			data=None,
			error_code=error_code,
			details=details
		)


# -------------------------------------------------
# 分页专用模型
# -------------------------------------------------
class PaginatedResponse(BaseModel, Generic[T]):
	total: int = Field(..., description="总条数")
	items: List[T] = Field(..., description="当前页数据")
	page: int = Field(..., description="当前页码")
	size: int = Field(..., description="每页大小")
	pages: int = Field(..., description="总页数")
	has_next: bool = Field(..., description="是否有下一页")
	has_prev: bool = Field(..., description="是否有上一页")


class PaginationParams(BaseModel):
	page: int = Query(1, ge=1, description="页码")
	size: int = Query(20, ge=1, le=100, description="每页大小")
	keyword: Optional[str] = Field(None, max_length=64, description="关键字模糊匹配")
